package com.sitech.util.spring;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.sitech.BaseConst;

/**
 * ClassName:ResourcePatternResolver Function: TODO ADD FUNCTION Reason: TODO
 * ADD REASON
 * 
 * @author geutopia
 * @version
 * @since Ver 1.1
 * @Date 2011 Jan 13, 2011 6:44:30 PM
 * 
 * @see
 */

public class ResourcePatternResolver extends PathMatchingResourcePatternResolver
{
	private static final Log logger = LogFactory.getLog(ResourcePatternResolver.class);

	/**
	 * Find all resources that match the given location pattern via the
	 * Ant-style PathMatcher. Supports resources in jar files and zip files and
	 * in the file system.
	 * 
	 * @param locationPattern
	 *            the location pattern to match
	 * @return the result as Resource array
	 * @throws IOException
	 *             in case of I/O errors
	 * @see #doFindPathMatchingJarResources
	 * @see #doFindPathMatchingFileResources
	 * @see org.springframework.util.PathMatcher
	 */
	protected Resource[] findPathMatchingResources(String locationPattern) throws IOException
	{
		String rootDirPath = determineRootDir(locationPattern);
		String subPattern = locationPattern.substring(rootDirPath.length());
		Resource[] rootDirResources = getResources(rootDirPath);
		String webRoot = BaseConst.WEBROOT_PATH;

		if (webRoot != null && !webRoot.equals(""))
		{
			File file = new File(webRoot);

			if (file.isDirectory())
			{
				File file2 = new File(file, "WEB-INF/lib");
				File[] libFiles = file2.listFiles();

				for (File jarFile : libFiles)
				{
					String jarFilePath = jarFile.getAbsolutePath();
					if (jarFilePath.endsWith(".jar"))
					{
						String temp = "jar:" + jarFile.toURI().toURL().toString() + "!/";
						URL url = new URL(temp);
						UrlResource urlResource = new UrlResource(url);
						rootDirResources = (Resource[]) ArrayUtils.add(rootDirResources, urlResource);
					}
				}
			}
		}
		else
		{
			String value = System.getProperties().getProperty("java.class.path");

			if (value != null)
			{
				String[] jars = value.split(";");

				for (String jar : jars)
				{
					if (jar.endsWith(".jar"))
					{
						jar.replaceAll("\\\\", "/");
						String temp = "jar:file:/" + jar + "!/";
						URL url = new URL(temp);
						UrlResource urlResource = new UrlResource(url);
						rootDirResources = (Resource[]) ArrayUtils.add(rootDirResources, urlResource);
					}
				}
			}
		}

		Set<Resource> result = new LinkedHashSet<Resource>(16);

		List<String> jarResource = new ArrayList<String>();

		for (Resource rootDirResource : rootDirResources)
		{

			rootDirResource = resolveRootDirResource(rootDirResource);

			if (isJarResource(rootDirResource))
			{
				String jarName = getJarName(rootDirResource);

				if (!checkSamejar(jarName, jarResource))
				{
					result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));
				}

				jarResource.add(jarName);
			}
			else
			{
				result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
			}

		}
		if (logger.isDebugEnabled())
		{
			logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result);
		}
		return result.toArray(new Resource[result.size()]);
	}

	private String getJarName(Resource resource)
	{
		try
		{
			String path = resource.getURL().toString();
			String jarName = path.substring(0, path.indexOf("!/"));
			jarName = jarName.replaceAll("\\\\", "/");
			jarName = jarName.substring(jarName.lastIndexOf("/"));
			return jarName;
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return null;
	}

	private boolean checkSamejar(String jarName, List<String> jarResource)
	{
		for (String jar : jarResource)
		{
			if (jar != null && jar.equals(jarName))
			{
				return true;
			}
		}

		return false;
	}

}
